home *** CD-ROM | disk | FTP | other *** search
/ Ultra Pack / UltraComputing Partner Applications.iso / SunLabs / tclTK / src / tk4.0 / tkAtom.c < prev    next >
C/C++ Source or Header  |  1995-02-23  |  4KB  |  166 lines

  1. /* 
  2.  * tkAtom.c --
  3.  *
  4.  *    This file manages a cache of X Atoms in order to avoid
  5.  *    interactions with the X server.  It's much like the Xmu
  6.  *    routines, except it has a cleaner interface (caller
  7.  *    doesn't have to provide permanent storage for atom names,
  8.  *    for example).
  9.  *
  10.  * Copyright (c) 1990-1994 The Regents of the University of California.
  11.  * Copyright (c) 1994 Sun Microsystems, Inc.
  12.  *
  13.  * See the file "license.terms" for information on usage and redistribution
  14.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  15.  */
  16.  
  17. static char sccsid[] = "@(#) tkAtom.c 1.11 95/02/23 11:03:53";
  18.  
  19. #include "tkPort.h"
  20. #include "tkInt.h"
  21.  
  22. /*
  23.  * Forward references to procedures defined in this file:
  24.  */
  25.  
  26. static void    AtomInit _ANSI_ARGS_((TkDisplay *dispPtr));
  27.  
  28. /*
  29.  *--------------------------------------------------------------
  30.  *
  31.  * Tk_InternAtom --
  32.  *
  33.  *    Given a string, produce the equivalent X atom.  This
  34.  *    procedure is equivalent to XInternAtom, except that it
  35.  *    keeps a local cache of atoms.  Once a name is known,
  36.  *    the server need not be contacted again for that name.
  37.  *
  38.  * Results:
  39.  *    The return value is the Atom corresponding to name.
  40.  *
  41.  * Side effects:
  42.  *    A new entry may be added to the local atom cache.
  43.  *
  44.  *--------------------------------------------------------------
  45.  */
  46.  
  47. Atom
  48. Tk_InternAtom(tkwin, name)
  49.     Tk_Window tkwin;        /* Window token;  map name to atom
  50.                  * for this window's display. */
  51.     char *name;            /* Name to turn into atom. */
  52. {
  53.     register TkDisplay *dispPtr;
  54.     register Tcl_HashEntry *hPtr;
  55.     int new;
  56.  
  57.     dispPtr = ((TkWindow *) tkwin)->dispPtr;
  58.     if (!dispPtr->atomInit) {
  59.     AtomInit(dispPtr);
  60.     }
  61.  
  62.     hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, name, &new);
  63.     if (new) {
  64.     Tcl_HashEntry *hPtr2;
  65.     Atom atom;
  66.  
  67.     atom = XInternAtom(dispPtr->display, name, False);
  68.     Tcl_SetHashValue(hPtr, atom);
  69.     hPtr2 = Tcl_CreateHashEntry(&dispPtr->atomTable, (char *) atom,
  70.         &new);
  71.     Tcl_SetHashValue(hPtr2, Tcl_GetHashKey(&dispPtr->nameTable, hPtr));
  72.     }
  73.     return (Atom) Tcl_GetHashValue(hPtr);
  74. }
  75.  
  76. /*
  77.  *--------------------------------------------------------------
  78.  *
  79.  * Tk_GetAtomName --
  80.  *
  81.  *    This procedure is equivalent to XGetAtomName except that
  82.  *    it uses the local atom cache to avoid contacting the
  83.  *    server.
  84.  *
  85.  * Results:
  86.  *    The return value is a character string corresponding to
  87.  *    the atom given by "atom".  This string's storage space
  88.  *    is static:  it need not be freed by the caller, and should
  89.  *    not be modified by the caller.  If "atom" doesn't exist
  90.  *    on tkwin's display, then the string "?bad atom?" is returned.
  91.  *
  92.  * Side effects:
  93.  *    None.
  94.  *
  95.  *--------------------------------------------------------------
  96.  */
  97.  
  98. char *
  99. Tk_GetAtomName(tkwin, atom)
  100.     Tk_Window tkwin;        /* Window token;  map atom to name
  101.                  * relative to this window's
  102.                  * display. */
  103.     Atom atom;            /* Atom whose name is wanted. */
  104. {
  105.     register TkDisplay *dispPtr;
  106.     register Tcl_HashEntry *hPtr;
  107.  
  108.     dispPtr = ((TkWindow *) tkwin)->dispPtr;
  109.     if (!dispPtr->atomInit) {
  110.     AtomInit(dispPtr);
  111.     }
  112.  
  113.     hPtr = Tcl_FindHashEntry(&dispPtr->atomTable, (char *) atom);
  114.     if (hPtr == NULL) {
  115.     char *name;
  116.     Tk_ErrorHandler handler;
  117.     int new, mustFree;
  118.  
  119.     handler= Tk_CreateErrorHandler(dispPtr->display, BadAtom,
  120.         -1, -1, (Tk_ErrorProc *) NULL, (ClientData) NULL);
  121.     name = XGetAtomName(dispPtr->display, atom);
  122.     mustFree = 1;
  123.     if (name == NULL) {
  124.         name = "?bad atom?";
  125.         mustFree = 0;
  126.     }
  127.     Tk_DeleteErrorHandler(handler);
  128.     hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, (char *) name,
  129.         &new);
  130.     Tcl_SetHashValue(hPtr, atom);
  131.     if (mustFree) {
  132.         XFree(name);
  133.     }
  134.     name = Tcl_GetHashKey(&dispPtr->nameTable, hPtr);
  135.     hPtr = Tcl_CreateHashEntry(&dispPtr->atomTable, (char *) atom,
  136.         &new);
  137.     Tcl_SetHashValue(hPtr, name);
  138.     }
  139.     return (char *) Tcl_GetHashValue(hPtr);
  140. }
  141.  
  142. /*
  143.  *--------------------------------------------------------------
  144.  *
  145.  * AtomInit --
  146.  *
  147.  *    Initialize atom-related information for a display.
  148.  *
  149.  * Results:
  150.  *    None.
  151.  *
  152.  * Side effects:
  153.  *    Tables get initialized, etc. etc..
  154.  *
  155.  *--------------------------------------------------------------
  156.  */
  157.  
  158. static void
  159. AtomInit(dispPtr)
  160.     register TkDisplay *dispPtr;    /* Display to initialize. */
  161. {
  162.     dispPtr->atomInit = 1;
  163.     Tcl_InitHashTable(&dispPtr->nameTable, TCL_STRING_KEYS);
  164.     Tcl_InitHashTable(&dispPtr->atomTable, TCL_ONE_WORD_KEYS);
  165. }
  166.